package com.kuaimacode.kframework.admin.services.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kuaimacode.kframework.admin.services.agent.SysAgentService;
import com.kuaimacode.kframework.admin.vo.response.UserWithdrawalVO;
import com.kuaimacode.kframework.common.Constant;
import com.kuaimacode.kframework.component.SmsSendService;
import com.kuaimacode.kframework.exception.ErrorEnum;
import com.kuaimacode.kframework.exception.ServerInternalErrorException;
import com.kuaimacode.kframework.mybatis.mapper.user.UserBankCardAccountMapper;
import com.kuaimacode.kframework.mybatis.mapper.user.UserDrawApplyMapper;
import com.kuaimacode.kframework.mybatis.models.user.User;
import com.kuaimacode.kframework.mybatis.models.user.UserBankCardAccount;
import com.kuaimacode.kframework.mybatis.models.user.UserDrawApply;
import com.kuaimacode.kframework.mybatis.models.user.UserWithdrawalPO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author qinyong
 * @Title:
 * @Package com.kuaimacode.kframework.admin.services.user
 * @Description: created by IntelliJ IDEA
 * @date 2019-05-25 09:32
 */
@Service
public class UserDrawApplyService extends ServiceImpl<UserDrawApplyMapper, UserDrawApply> {

    @Autowired
    private UserService userService;
    @Autowired
    private SmsSendService smsSendService;
    @Autowired
    private UserBankCardAccountMapper userBankCardAccountMapper;
    @Autowired
    private SysAgentService agentService;

    /**
     * 查询普通用户的提现申请
     * @return
     */
    public PageInfo<UserWithdrawalVO> findNormalUserDrawApply(int pageNum, int pageSize, UserWithdrawalVO searchVO) {

        PageHelper.startPage(pageNum, pageSize);
        UserWithdrawalPO searchPO = new UserWithdrawalPO();
        BeanUtils.copyProperties(searchVO, searchPO);
        List<UserWithdrawalPO> withdrawalPOS = baseMapper.findNormalUserDrawApply(searchPO);

        if (withdrawalPOS == null) {
            return new PageInfo<>();
        }
        PageInfo pageInfo = PageInfo.of(withdrawalPOS);
        pageInfo.setList(withdrawalPOS.stream().map(withdrawalPO -> {
            UserWithdrawalVO resp = new UserWithdrawalVO();
            BeanUtils.copyProperties(withdrawalPO, resp);
            BigDecimal applyAmount = new BigDecimal(withdrawalPO.getApplyAmount());
            resp.setRealAmount(applyAmount.subtract(applyAmount.multiply(withdrawalPO.getRatio()).setScale(2, BigDecimal.ROUND_HALF_UP)));
            return resp;
        }).collect(Collectors.toList()));
        return pageInfo;
    }

    /**
     * 查询普通用户提现申请
     * @param id
     * @return
     */
    public UserWithdrawalVO findSingleNormalUserDrawApply(Long id) {

        UserWithdrawalPO searchPO = new UserWithdrawalPO();
        searchPO.setId(id);
        List<UserWithdrawalPO> withdrawalPOS = baseMapper.findNormalUserDrawApply(searchPO);

        if (withdrawalPOS == null) {
            return new UserWithdrawalVO();
        }
        UserWithdrawalVO withdrawalVO = new UserWithdrawalVO();
        BeanUtils.copyProperties(withdrawalPOS.get(0), withdrawalVO);
        return withdrawalVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void approval(Long id, UserWithdrawalVO withdrawalVO) {
        UserDrawApply userDrawApply = baseMapper.selectById(id);
        Optional.ofNullable(userDrawApply)
                .filter(drawApply -> "1".equals(drawApply.getApplyStatus()))
                .orElseThrow(() -> new ServerInternalErrorException(ErrorEnum.USER_WITHDRAWAL_STATUS_ERROR));

        QueryWrapper<UserBankCardAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userDrawApply.getUserId());
        UserBankCardAccount bankCardAccount = userBankCardAccountMapper.selectOne(wrapper);
        Map<String, Object> smsParams = new HashMap<>();
        smsParams.put("phone", bankCardAccount.getBankCardPhoneNumber());
        smsParams.put("name", bankCardAccount.getCardUserName());
        smsParams.put("card", bankCardAccount.getBankCardNumber());
        smsParams.put("amount", userDrawApply.getApplyAmount());
        //同意申请
        BigDecimal applyAmount = new BigDecimal(userDrawApply.getApplyAmount());
        User user = userService.getById(userDrawApply.getUserId());
        BigDecimal serviceCharge = applyAmount.multiply(userDrawApply.getRatio()).setScale(2, BigDecimal.ROUND_HALF_UP);
        if ("2".equals(withdrawalVO.getApplyStatus())) {
            //增加平台收入
            agentService.changeBalance(user.getAgentId(), Constant.InOutEnum.IN, serviceCharge,
                    Constant.AgentAccountTranTypeEnum.FEE, "用户[" + user.getPhone() + "]提现手续费", userDrawApply.getId().toString());
            //减少账户余额
//            userService.decreaseAccountBalance(userDrawApply.getUserId(), applyAmount, "6", "提现减少");
            //发送同意提醒短信
            smsParams.put("ratio", serviceCharge);
            smsParams.put("realAmount", applyAmount.subtract(serviceCharge));
            smsSendService.sendAgreeWithdrawalMsg(userService.getById(userDrawApply.getUserId()).getPhone(), smsParams);
            //拒绝申请
        } else if ("3".equals(withdrawalVO.getApplyStatus())) {
            //用户拒绝
            userService.decreaseAccountBalance(userDrawApply.getUserId(), applyAmount, "6", "用户提现拒绝");
            //平台余额更新
//            agentService.changeBalance(user.getAgentId(), Constant.InOutEnum.OUT, serviceCharge,
//                    Constant.AgentAccountTranTypeEnum.DRAW, "用户[" + user.getPhone() + "]提现手续费失败退回", userDrawApply.getId().toString());
            smsParams.put("reason", withdrawalVO.getReason());
            smsSendService.sendRejectWithdrawalMsg(userService.getById(userDrawApply.getUserId()).getPhone(), smsParams);
        }
        //修改申请单状态
        UserDrawApply update = new UserDrawApply();
        update.setId(userDrawApply.getId());
        update.setApplyStatus(withdrawalVO.getApplyStatus());
        Optional.ofNullable(withdrawalVO.getReason())
                .ifPresent(update::setReason);
        baseMapper.updateById(update);
    }

    /**
     * 查询数量
     * param status 1-申请 2-审批 3-拒绝
     * param type 1-用户 2-师傅
     * @return
     */
    public int count(Integer status, Integer type) {
        QueryWrapper<UserDrawApply> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1);
        wrapper.eq("apply_status", status);
        List<UserDrawApply> list = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        BigDecimal amount = new BigDecimal(0);
        int count = 0;
        for (UserDrawApply apply : list) {
            User user = userService.getById(apply.getUserId());
            if(user != null){
                if(type == 1){
                    //用户
                    if(!user.isOneMaster()){
                        count++;
                    }
                }else{
                    //师傅
                    if(user.isOneMaster()){
                        count++;
                    }
                }
            }
        }
        return count;
    }
}
